package com.tencent.supersonic.headless.core.adaptor.db;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.UnaryOperator;

import com.tencent.supersonic.common.jsqlparser.SqlReplaceHelper;
import com.tencent.supersonic.common.pojo.Constants;
import com.tencent.supersonic.common.pojo.enums.TimeDimensionEnum;

import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;

public class OracleAdaptor extends DbAdaptor {

	@Override
	public String getDateFormat(String dateType, String dateFormat, String column) {
		// TODO Auto-generated method stub
		if (dateFormat.equalsIgnoreCase(Constants.DAY_FORMAT_INT)) {
            if (TimeDimensionEnum.MONTH.name().equalsIgnoreCase(dateType)) {
                return "TO_DATE(%s, 'YY-MM')".replace("%s", column);
            } else if (TimeDimensionEnum.WEEK.name().equalsIgnoreCase(dateType)) {
                //return "DATE_FORMAT(DATE_SUB(%s, INTERVAL (DAYOFWEEK(%s) - 2) DAY), '%Y-%m-%d')".replace("%s", column);
            } else {
                return "TO_DATE(%s, 'YYMMDD')".replace("%s", column);
            }
        } else if (dateFormat.equalsIgnoreCase(Constants.DAY_FORMAT)) {
            if (TimeDimensionEnum.MONTH.name().equalsIgnoreCase(dateType)) {
                return "TO_DATE(%s, 'YY-MM') ".replace("%s", column);
            } else if (TimeDimensionEnum.WEEK.name().equalsIgnoreCase(dateType)) {
                //return "DATE_FORMAT(DATE_SUB(%s, INTERVAL (DAYOFWEEK(%s) - 2) DAY), '%Y-%m-%d')".replace("%s", column);
            } else {
                return column;
            }
        }
        return column;
	}

	@Override
	public String getColumnMetaQueryTpl() {
		// TODO Auto-generated method stub
		String sql = "select col.column_name \"name\" ,"
                + "col.DATA_TYPE \"dataType\", "
                + "c.comments AS \"comment\" "
                + "from user_tab_columns col "
                + "LEFT JOIN all_col_comments c ON c.column_name = col.column_name AND c.table_name = col.table_name "
                + "where col.table_name = '%s' ORDER BY col.column_id";
		return sql;
	}

	@Override
	public String getDbMetaQueryTpl() {
		// TODO Auto-generated method stub
		return "SELECT username \"name\" FROM all_users";
	}

	@Override
	public String getTableMetaQueryTpl() {
		// TODO Auto-generated method stub
		return "select t.table_name \"name\" from user_tables t ORDER by t.table_name asc";
	}

	@Override
	public String functionNameCorrector(String sql) {
		// TODO Auto-generated method stub
		Map<String, String> functionMap = new HashMap<>();
        functionMap.put("MONTH".toLowerCase(), "TO_CHAR");
        functionMap.put("DAY".toLowerCase(), "TO_CHAR");
        functionMap.put("YEAR".toLowerCase(), "TO_CHAR");
        Map<String, UnaryOperator> functionCall = new HashMap<>();
        functionCall.put("MONTH".toLowerCase(), o -> {
            if (Objects.nonNull(o) && o instanceof ExpressionList) {
                ExpressionList expressionList = (ExpressionList) o;
                expressionList.add(new StringValue("MM"));
                return expressionList;
            }
            return o;
        });
        functionCall.put("DAY".toLowerCase(), o -> {
            if (Objects.nonNull(o) && o instanceof ExpressionList) {
                ExpressionList expressionList = (ExpressionList) o;
                expressionList.add(new StringValue("dd"));
                return expressionList;
            }
            return o;
        });
        functionCall.put("YEAR".toLowerCase(), o -> {
            if (Objects.nonNull(o) && o instanceof ExpressionList) {
                ExpressionList expressionList = (ExpressionList) o;
                expressionList.add(new StringValue("YYYY"));
                return expressionList;
            }
            return o;
        });
        return SqlReplaceHelper.replaceFunction(sql, functionMap, functionCall);
	}

}
